﻿using Corina.Commands;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Corina.Cydee.Apphub.Viewmodels
{
    public class GuobiaoDocumentViewmodel : ViewmodelBase
    {
        public GuobiaoDocumentViewmodel()
        {
            DocumentClient.GetAllGuobiaoDocumentItemsCompleted += GetAllGuobiaoDocumentItemsCompleted;
            DocumentClient.SaveGuobiaoInfoCompleted += SaveGuobiaoInfoCompleted;
            UploaderClient.AppendToFileCompleted += AppendToFileCompleted;

            if(DataContext.IsValid)
            {
                LoadData();
            }
        }

        #region Methods
        private void SaveGuobiaoInfoCompleted(object sender, DataService.SaveGuobiaoInfoCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                Deployment.Current.Dispatcher.BeginInvoke(delegate()
                {
                    Uploading = false;
                    _leftLength = 0;
                    _actual_length = 0;
                    _stream = null;
                    _start = 0;
                    ChooseFile = null;
                    ShowUploadView = false;
                    LoadData();
                });
            }
        }        

        private void AppendToFileCompleted(object sender, DataService.AppendToFileCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (_leftLength > 0)
                {
                    _stream.Position = _start;
                    _actual_length = 0;
                    if (_leftLength < _maxLength)
                    {
                        _upload_bytes = new byte[_leftLength];
                        _actual_length = _stream.Read(_upload_bytes, 0, (int)_leftLength);
                    }
                    else
                    {
                        _upload_bytes = new byte[_maxLength];
                        _actual_length = _stream.Read(_upload_bytes, 0, _maxLength);
                    }
                    _start += _actual_length;
                    _leftLength -= _actual_length;
                    if (_actual_length > 0)
                    {
                        UploaderClient.AppendToFileAsync(Filename, "Guobiao", false, false, Convert.ToBase64String(_upload_bytes));
                    }
                }
                else
                {
                    Deployment.Current.Dispatcher.BeginInvoke(delegate()
                    {
                        DocumentClient.SaveGuobiaoInfoAsync(Account, Password, Filename, GBCode, Name, Description);
                    });
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        private void GetAllGuobiaoDocumentItemsCompleted(object sender, DataService.GetAllGuobiaoDocumentItemsCompletedEventArgs e)
        {
            if(e.Error == null)
            {
                if(e.Result.Result == Enumerations.ResultValue.Succeed)
                {
                    var items = (from t in e.Result.DataObjects
                                 select new
                                 {
                                     ItemIndex = t["ROW_NUMBER"],
                                     Id = t["Id"],
                                     Name = t["Name"],
                                     Code = t["Code"],
                                     Filename = t["DocumentName"],
                                     Description = t["Description"]
                                 });
                    ItemsCollection = new ObservableCollection<object>(items);
                    ItemsCount = e.Result.TotalCount;
                }
            }
            IsBusy = false;
        }

        protected override void LoadData(params object[] paras)
        {
            IsBusy = true;
            DocumentClient.GetAllGuobiaoDocumentItemsAsync(Account, Password, "", Index, 20);
        } 
        #endregion

        #region Collection
        private ObservableCollection<object> _itemsCollection;
        public ObservableCollection<object> ItemsCollection
        {
            get { return _itemsCollection; }
            set
            {
                _itemsCollection = value;
                RaisePropertyChanged(() => ItemsCollection);
            }
        }
        #endregion

        #region Properties
        private bool _showUploadView = false;
        public bool ShowUploadView
        {
            get { return _showUploadView; }
            set
            {
                _showUploadView = value;
                RaisePropertyChanged(() => ShowUploadView);
            }
        }

        private FileInfo _chooseFile;
        public FileInfo ChooseFile
        {
            get { return _chooseFile; }
            set
            {
                _chooseFile = value;
                RaisePropertyChanged(() => ChooseFile);
                Filename = ChooseFile != null ? ChooseFile.Name : "";
                RaisePropertyChanged(() => UploadCommand);
            }
        }

        private string _filename;
        public string Filename
        {
            get { return _filename; }
            set
            {
                _filename = value;
                RaisePropertyChanged(() => Filename);
                RaisePropertyChanged(() => UploadCommand);
            }
        }

        private string _gbCode;
        public string GBCode
        {
            get { return _gbCode; }
            set
            {
                _gbCode = value;
                RaisePropertyChanged(() => GBCode);
                RaisePropertyChanged(() => UploadCommand);
            }
        }

        private string _description;
        public string Description
        {
            get { return _description; }
            set
            {
                _description = value;
                RaisePropertyChanged(() => Description);
            }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged(() => Name);
            }
        }
        #endregion

        #region Upload
        private long _leftLength = 0;

        private byte[] _upload_bytes = new byte[0];

        private int _maxLength = 1024 * 1024;//_all_file_bytes.Length;

        private int _start = 0;

        private int _actual_length = 0;

        private FileStream _stream;

        private void StartUpload()
        {
            Task task = Task.Factory.StartNew(() =>
            {
                _stream = ChooseFile.OpenRead();
            });

            task.ContinueWith(t =>
            {
                _leftLength = _stream.Length;
                _stream.Position = _start;
                _actual_length = 0;
                if (_leftLength < _maxLength)
                {
                    _upload_bytes = new byte[_leftLength];
                    _actual_length = _stream.Read(_upload_bytes, 0, (int)_leftLength);
                }
                else
                {
                    _upload_bytes = new byte[_maxLength];
                    _actual_length = _stream.Read(_upload_bytes, 0, _maxLength);
                }
                _start += _actual_length;
                _leftLength -= _actual_length;
                if(_actual_length>0)
                {
                    UploaderClient.AppendToFileAsync(Filename, "Guobiao", true, true, Convert.ToBase64String(_upload_bytes));
                }
            });
        }

        private bool _uploading = false;
        public bool  Uploading
        {
            get { return _uploading; }
            set
            {
                _uploading = value;
                RaisePropertyChanged(() => Uploading);
            }
        }
        #endregion

        #region Commands
        public ICommand SubmitCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate { }
                };
            }
        }

        public ICommand OpenDialogCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        OpenFileDialog dialog = new OpenFileDialog();
                        dialog.ShowDialog();
                        if (dialog.File != null)
                        {
                            ChooseFile = dialog.File;
                        }
                    }
                };
            }
        }

        public ICommand UploadCommand
        {
            get {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return ChooseFile != null; },
                    ExecuteCallback = delegate
                    {
                        Uploading = true;
                        StartUpload();
                    }
                };
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate {
                        ShowUploadView = false;
                        ChooseFile = null;
                    }
                };
            }
        }
        #endregion
    }
}
